/*
 * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.wels.sample.slice;

import com.wels.sample.ResourceTable;

import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;

import ohos.agp.components.Button;
import ohos.agp.components.Component;
import ohos.agp.window.dialog.ToastDialog;
import ohos.app.Environment;
import ohos.bundle.IBundleManager;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.Vector;

/**
 * EncoderAbilitySlice Class
 */
public class EncoderAbilitySlice extends AbilitySlice {
    private static final HiLogLabel TAG = new HiLogLabel(3, 0xD000F00, EncoderAbilitySlice.class.getSimpleName());
    String mStreamPath;
    String mStreamPathAuto;
    Vector<String> mCfgFiles = new Vector<String>();
    boolean hasStorageReadWritePermission = false;

    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_ability_encoder);

        hasStorageReadWritePermission =
                verifySelfPermission("ohos.permission.READ_USER_STORAGE") == IBundleManager.PERMISSION_GRANTED &&
                verifySelfPermission("ohos.permission.WRITE_USER_STORAGE") == IBundleManager.PERMISSION_GRANTED;

        mStreamPath = getContext().getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS) + "/manual_encode/";
        mStreamPathAuto = getContext().getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS) + "/auto_encode/";

        Component autoComp = findComponentById(ResourceTable.Id_buttonAuto);
        if (autoComp instanceof Button) {
            Button autoEncoding = (Button) autoComp;
            setClickedListenerForAuto(autoEncoding);
        }

        Component loadComp = findComponentById(ResourceTable.Id_cfg);
        if (loadComp instanceof Button) {
            Button loadButton = (Button) loadComp;
            loadButton.setClickedListener(new Component.ClickedListener() {
                @Override
                public void onClick(Component component) {
                    setClickedListenerForLoad();
                }
            });
        }

        Component showComp = findComponentById(ResourceTable.Id_buttonSW);
        if (showComp instanceof Button) {
            Button showButton = (Button) showComp;
            showButton.setClickedListener(new Component.ClickedListener() {
                @Override
                public void onClick(Component component) {
                    setClickedListernerForShow();
                }
            });
        }
    }

    private void setClickedListenerForAuto(Button autoEncoding) {
        autoEncoding.setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                if (hasStorageReadWritePermission) {
                    runAutoEnc();
                } else {
                    new ToastDialog(getContext())
                            .setText("App does not have READ/WRITE permission to staorage")
                            .show();
                }
            }
        });
    }

    private void setClickedListernerForShow() {
        HiLog.info (TAG, "encode sequence number = " + mCfgFiles.size());
        if (hasStorageReadWritePermission) {
            for (int k = 0; k < mCfgFiles.size(); k++) {
                String cfgFile = mCfgFiles.get(k);
                DoEncoderTest(cfgFile);
            }
            mCfgFiles.clear();
            new ToastDialog(getContext())
                    .setText("Encoding successful")
                    .show();
        } else {
            new ToastDialog(getContext())
                    .setText("App does not have READ/WRITE permission to staorage")
                    .show();
        }
    }

    private void setClickedListenerForLoad() {
        if (hasStorageReadWritePermission) {
            String cfgFile = mStreamPath + "cfgs.txt";
            try (BufferedReader bufferedReader = new BufferedReader(new FileReader(cfgFile))) {
                String text;
                while ((text = bufferedReader.readLine()) != null) {
                    mCfgFiles.add(mStreamPath + text);
                    HiLog.info(TAG, mStreamPath + text);
                }
            } catch (IOException e) {
                HiLog.error(TAG, e.getMessage());
            }
        } else {
            new ToastDialog(getContext())
                    .setText("App does not have READ/WRITE permission to staorage")
                    .show();
        }
    }

    /**
     * runAutoEnc
     */
    public void runAutoEnc() {
        Thread thread = new Thread() {
            /**
             * run
             */
            public void run() {
                HiLog.info(TAG, "encoder performance test begin");
                File encCase = new File (mStreamPathAuto);
                String[] caseNum = encCase.list();
                if (caseNum == null || caseNum.length == 0) {
                    HiLog.info(TAG, "have not find any encoder resourse");
                    terminate();
                }

                autoDecodeMethodCall(caseNum);
                HiLog.info(TAG, "encoder performance test finish");
            }
        };
        thread.start();
    }

    private void autoDecodeMethodCall(String[] caseNum) {
        String inYuvfile = null;
        String outBitfile = null;
        String inOrgfile = null;
        String inLayerfile = null;
        File encCaseNo = new File (mStreamPathAuto);
        String[] encFile = caseNum;

        for (int k = 0; k < encFile.length; k++) {
            if (encFile[k].compareToIgnoreCase ("welsenc.cfg") == 0) {
                inOrgfile = encCaseNo + File.separator + encFile[k];
            } else if (encFile[k].compareToIgnoreCase ("layer2.cfg") == 0) {
                    inLayerfile = encCaseNo + File.separator + encFile[k];
                } else {
                    if (encFile[k].compareToIgnoreCase ("Cisco_Absolute_Power_1280x720_30fps.yuv") == 0) {
                        inYuvfile = encCaseNo + File.separator + encFile[k];
                    }
                }
        }
        outBitfile = inYuvfile + ".264";
        DoEncoderAutoTest (inOrgfile, inLayerfile, inYuvfile, outBitfile);
    }

    /**
     * DoEncoderTest
     *
     * @param cfgFileName cfgFileName
     */
    public native void  DoEncoderTest (String cfgFileName);

    /**
     * DoEncoderAutoTest
     *
     * @param cfgFileName cfgFileName
     * @param layerFileName layerFileName
     * @param outBitsName outBitsName
     * @param yuvFileName yuvFileName
     */
    public native void  DoEncoderAutoTest (String cfgFileName, String layerFileName,
                                            String yuvFileName, String outBitsName);

    static {
        System.loadLibrary ("openh264");
        System.loadLibrary ("stlport_shared");
        System.loadLibrary ("encoding");
        HiLog.info(TAG, "Load libwelsencdemo.so successful");
    }
}